﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using Cost.Models;
using Cost.Services;
using Cost.Services.Services;
using NBlock.Components.ImportExport;
using NBlock.Core;
using NBlock.Core.ORM;
using NBlock.MVCExtensions;

namespace Cost.Controllers
{
    public class MaterialDeliveryController : Controller
    {
        #region 构造函数
        private readonly ICostRepository<MaterialDeliveryPlanView> materialDeliveryPlanViewRepository;
        private readonly ICostRepository<MaterialDelivery> materialDeliveryRepository;
        private readonly ICostRepository<MaterialDeliveryItem> materialDeliveryItemRepository;
        private readonly ICostRepository<Storage> storageRepository;
        private readonly ICostRepository<StockRecord> stockrecordRepository;
        private readonly MaterialService materialService;
        private readonly IEnumService enumService;
        private readonly IWordExporter wordExporter;
        private readonly StorageService storageService;
        public MaterialDeliveryController(ICostRepository<MaterialDeliveryPlanView> materialDeliveryPlanViewRepository,
            ICostRepository<MaterialDelivery> materialDeliveryRepository,
            ICostRepository<MaterialDeliveryItem> materialDeliveryItemRepository,
            ICostRepository<Storage> storageRepository,
            ICostRepository<StockRecord> stockrecordRepository,
            MaterialService materialService,
            IEnumService enumService,
            IWordExporter wordExporter,
            StorageService storageService)
        {
            this.materialDeliveryPlanViewRepository = materialDeliveryPlanViewRepository;
            this.materialDeliveryRepository = materialDeliveryRepository;
            this.materialDeliveryItemRepository = materialDeliveryItemRepository;
            this.storageRepository = storageRepository;
            this.stockrecordRepository = stockrecordRepository;
            this.materialService = materialService;
            this.enumService = enumService;
            this.storageService = storageService;
            this.wordExporter = wordExporter;
        }
        #endregion

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Edit(string Id, string siteId, DateTime? date)
        {
            var data = materialDeliveryRepository.Find(Id) ?? new MaterialDelivery
            {
                State = "Draft",
                SiteID = siteId,
                Date = date ?? DateTime.Now.AddDays(1),
                OrderDate = date,
            };

            // 子表数据
            var items = GetItems(Id, siteId, date);
            ViewBag.MaterialList = items;

            data.TotalWeight = Math.Ceiling(items.Sum(m => m.DeliveryWeight) * 100) / 100;
            data.TotalAmount = Math.Ceiling(items.Sum(m => m.Amount) * 100) / 100;

            return View(data);
        }

        private IList<MaterialDeliveryItem> GetItems(string orderId, string siteId, DateTime? date)
        {
            // 从采购计划中产生明细
            if (!string.IsNullOrEmpty(siteId))
            {
                var list = materialDeliveryPlanViewRepository.FindAll(p => p.SiteId == siteId && p.Date == date)
                   .ToList().Select(p => new MaterialDeliveryItem
                   {
                       Id = Guid.NewGuid().ToString(),
                       Amount = p.TotalAmount.Value,
                       Code = p.Code,
                       Category = p.Category,
                       Date = p.Date,
                       DeliveryWeight = p.TotalWeight.Value,
                       OrderWeight = p.TotalWeight.Value,
                       Price = materialService.GetMaterialPrice(p.Id, p.NeedProcess, p.Date),
                       SignWeight = p.TotalWeight.Value,
                       MaterialId = p.Id,
                       Name = p.Name,
                       SiteID = p.SiteId,
                       Unit = p.Unit,
                       NeedProcess = p.NeedProcess,
                       State = "Draft",
                   }).ToList();

                return list;
            }
            else
            {
                var list = materialDeliveryItemRepository.FindAll(d => d.OrderId == orderId).ToList();
                return list;
            }
        }

        [HttpPost]
        public JsonResult Save(string Id, IList<MaterialDeliveryItem> MaterialList)
        {
            var data = materialDeliveryRepository.Find(Id) ?? new MaterialDelivery();
            TryUpdateModel(data);

            // 如果不是草稿，则不能保存只能查看
            if (data.State != "Draft")
            {
                return Json(new nbAjaxMessage
                {
                    IsSuccess = false,
                    Msg = "送货单状态已经不是草稿了，只能查看，不允许保存。"
                });
            }

            if (!string.IsNullOrWhiteSpace(data.SiteID))
            {
                data.SiteName = enumService.GetEnumText("ProjectSite", data.SiteID);
            }

            var ItemDesc = string.Empty;
            decimal totalAmount = 0;
            decimal totalWeight = 0;
            // 先删除所有子表，再保持所有子表数据
            materialDeliveryItemRepository.DeleteAll(m => m.OrderId == data.Id);
            if (MaterialList != null)
            {
                foreach (var m in MaterialList)
                {
                    m.OrderId = data.Id;
                    m.SiteID = data.SiteID;
                    m.State = "Draft";
                    m.Date = data.Date;
                    m.Amount = materialService.GetMaterialPrice(m.MaterialId, m.NeedProcess, m.Date) * m.DeliveryWeight;
                    materialDeliveryItemRepository.Insert(m);

                    // 计算总价格和品名汇总
                    ItemDesc += string.Concat(m.Name, ",");
                    totalAmount += m.Amount;
                    totalWeight += m.DeliveryWeight;
                }
            }
            data.ItemDesc = ItemDesc.Trim(',');
            data.TotalAmount = totalAmount;
            data.TotalWeight = totalWeight;
            materialDeliveryRepository.Save(data);
            return Json(nbAjaxMessage.Successful);
        }

        [HttpPost]
        public JsonResult Delete(string Id)
        {
            materialDeliveryRepository.Delete(Id);
            materialDeliveryItemRepository.DeleteAll(m => m.OrderId == Id);
            return Json(nbAjaxMessage.Successful);
        }

        [HttpPost]
        public JsonResult List(DateTime? date, nbPageInfo pager, nbSearchCondition where)
        {
            Expression<Func<MaterialDelivery, bool>> filter = null;
            if (date.HasValue)
            {
                filter = p => p.Date == date && p.State == "Draft";
            }

            var pageData = materialDeliveryRepository.GetPageable(pager, filter, where);
            var data = pager.ToGridData(pageData);
            return Json(data);
        }

        #region 送货
        [HttpPost]
        public JsonResult Delivery(string Id)
        {
            var ids = Id.Split(',');
            var Purchases = materialDeliveryRepository.FindAll(p => ids.Contains(p.Id)).ToList();
            foreach (var p in Purchases)
            {
                p.State = "Delivery";
                materialDeliveryRepository.Update(p);
                //查找所有明细数据
                var itemList = materialDeliveryItemRepository.FindAll(m => m.OrderId == p.Id).ToList();
                foreach (var m in itemList)
                {
                    m.State = "Delivery";
                    materialDeliveryItemRepository.Update(m);

                    // 出库
                    storageService.StorageOut(m.MaterialId, m.DeliveryWeight, "送货单");
                }
            }

            return Json(nbAjaxMessage.Successful);
        }
        #endregion

        #region 签收
        public ActionResult Sign(string Id)
        {
            var data = materialDeliveryRepository.Find(Id);
            if (data.State != "Delivery")
            {
                throw new Exception(string.Format("当前送货单（{0}）的状态不是送货，所以无法签收！", Id));
            }

            // 子表数据
            var items = GetSignItems(Id);
            ViewBag.detail = items;

            return View(data);
        }

        public IList<MaterialDeliveryItem> GetSignItems(string orderId)
        {
            var list = materialDeliveryItemRepository.FindAll(p => p.OrderId == orderId).ToList();
            return list;
        }

        [HttpPost]
        public JsonResult Sign(string Id, IList<MaterialDeliveryItem> detail)
        {
            var data = materialDeliveryRepository.Find(Id);
            data.State = "Sign";

            decimal totalAmount = 0;
            decimal totalWeight = 0;
            // 先删除所有子表，再保持所有子表数据
            materialDeliveryItemRepository.DeleteAll(m => m.OrderId == data.Id);
            foreach (var item in detail)
            {
                item.State = "Sign";
                item.Amount = item.Price * item.SignWeight;
                materialDeliveryItemRepository.Insert(item);

                // 计算总重量
                totalWeight += item.SignWeight;
                totalAmount += item.Amount;
            }
            data.TotalWeight = totalWeight;
            data.TotalAmount = totalAmount;
            materialDeliveryRepository.Save(data);
            return Json(nbAjaxMessage.Successful);
        }
        #endregion

        #region 送货计划
        public ActionResult Plan()
        {
            return View();
        }

        [HttpPost]
        public JsonResult PlanList(string siteId, DateTime? date, nbPageInfo pager, nbSearchCondition where)
        {
            Expression<Func<MaterialDeliveryPlanView, bool>> filter = m => m.SiteId == siteId;
            if (date.HasValue)
                filter = filter.And(m => m.Date == date);

            var list = materialDeliveryPlanViewRepository.GetPageable(pager, filter, where);
            var fdata = pager.ToGridData(list);
            return Json(fdata);
        }

        [HttpPost]
        public JsonResult PlanTree(string Id)
        {
            var list = new List<nbJsonTreeNode>();
            if (string.IsNullOrWhiteSpace(Id))
            {
                // 获取供应商的数据
                var items = enumService.GetEnumDataSource("ProjectSite");
                foreach (var item in items)
                {
                    list.Add(new nbJsonTreeNode
                    {
                        id = item.Value,
                        text = item.Text,
                        value = item.Value
                    });
                }
            }
            return Json(list);
        }
        #endregion

        #region 送货明细查询
        public ActionResult Detail()
        {
            return View();
        }

        [HttpPost]
        public JsonResult DetailList(DateTime? date, nbPageInfo pager, nbSearchCondition where)
        {
            Expression<Func<MaterialDeliveryItem, bool>> filter = null;
            if (date.HasValue)
            {
                filter = filter.And(m => m.Date == date);
            }

            var siteId = nbUserContext.Current.CurrentUser.UnitCode;
            if (!string.IsNullOrEmpty(siteId))
            {
                filter = filter.And(m => m.SiteID == siteId);
            }

            var list = materialDeliveryItemRepository.GetPageable(pager, filter, where);
            var fdata = pager.ToGridData(list);
            return Json(fdata);
        }
        #endregion

        #region 打印加工单
        public FileResult Export(string Id)
        {
            var ds = new DataSet();
            var ids = Id.Split(',');
            var deliveries = materialDeliveryRepository.FindAll(p => ids.Contains(p.Id)).ToList();
            var materials = materialDeliveryItemRepository.FindAll(item => ids.Contains(item.OrderId)).ToList();
            ds.AddNestedList(deliveries, materials, p => p.Id, c => c.OrderId, "Delivery", "Materials");

            var data = wordExporter.ExportPDF(ds, Server.MapPath("~/Upload/Templates/Delivery.doc"), e =>
            {
                if (e.FieldName == "Unit")
                    e.Text = enumService.GetEnumText("MaterialUnit", e.FieldValue.ToString());
            });

            return File(data, "Application/pdf");
        }
        #endregion
    }
}
